package user

import (
	"context"
	"strconv"
	"strings"

	"mall/common/modelx"
	"mall/common/utils/pointy"
	"mall/service/user/model"
	"mall/service/user/rpc/internal/svc"
	"mall/service/user/rpc/types/user"

	"github.com/zeromicro/go-zero/core/logx"
)

type BackendGetUserListLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewBackendGetUserListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *BackendGetUserListLogic {
	return &BackendGetUserListLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

// #24.08.24#
func (l *BackendGetUserListLogic) BackendGetUserList(in *user.UserListReq) (*user.UserListResp, error) {
	var orderBys []string
	if len(in.OrderBy) > 0 {
		for _, orderBy := range in.OrderBy {
			var order = " ASC"
			if orderBy.Order == "1" {
				order = " DESC"
			}
			if orderBy.Field == "id" {
				orderBys = append(orderBys, model.UserColumns.ID+order)
			}
			if orderBy.Field == "createdAt" {
				orderBys = append(orderBys, model.UserColumns.CreatedAt+order)
			}
		}
	}

	var stati string
	if len(in.FilterBy) > 0 {
		for _, filterBy := range in.FilterBy {
			if filterBy.Field == "status" {
				stati = filterBy.In
			}
		}
	}

	filterMap := make(map[string]map[string][]any)
	resp := &user.UserListResp{}
	if in.UserId != nil && *in.UserId > 0 {
		filterMap[model.UserColumns.ID] = map[string][]any{
			"equalTo": []any{*in.UserId},
		}
	}

	statusIn := modelx.UniqueInterfaces(stati, 32)
	statusMap := make(map[string][]any)
	if len(statusIn) > 0 {
		statusMap["in"] = statusIn
	}
	if in.Status != nil {
		statusMap["equalTo"] = []any{*in.Status}
	}
	filterMap[model.UserColumns.UserStatus] = statusMap

	if in.UserId != nil {
		filterMap[model.UserColumns.ID] = map[string][]any{
			"equalTo": []any{*in.UserId},
		}
	}
	if in.Mobile != nil {
		filterMap[model.UserColumns.UserMobile] = map[string][]any{
			"contain": []any{*in.Mobile},
		}
	}

	var orderBy string
	if len(orderBys) > 0 {
		orderBy = strings.Join(orderBys, ",")
	}
	res, count, err := l.svcCtx.User.GetList(l.ctx, model.M{
		"page":     int64(in.Page),
		"pageSize": int64(in.PageSize),
		"orderBy":  orderBy,
	}, 1, filterMap)
	if err != nil {
		return nil, err
	}
	resp.Total = uint64(count)
	if len(res) > 0 {
		for _, v := range res {
			var EmailVerified uint32
			var MobileVerified uint32
			var IsSystem uint32
			if v.UserEmailVerified > 0 {
				EmailVerified = 1
			}
			if v.UserMobileVerified > 0 {
				MobileVerified = 1
			}
			if v.IsSystem > 0 {
				IsSystem = 1
			}
			resp.List = append(resp.List, &user.TmpUserInfo{
				Id:       pointy.GetPointer(strconv.Itoa(int(v.ID))),
				Username: pointy.GetPointer(v.UserLogin),
				Email:    pointy.GetPointer(v.UserEmail),
				Mobile:   pointy.GetPointer(v.UserMobile),
				Status:   pointy.GetPointer(uint32(v.UserStatus)),
				// LastLoginTime:    pointy.GetPointer(modelx.FormatNullDotTime(v.LastLoginTime, "")),
				CreatedAt:        pointy.GetPointer(modelx.FormatTime(v.CreatedAt, "")),
				UpdatedAt:        pointy.GetPointer(modelx.FormatTime(v.UpdatedAt, "")),
				DeletedAt:        pointy.GetPointer(modelx.FormatNullDotTime(v.DeletedAt, "")),
				EmailVerified:    pointy.GetPointer(EmailVerified),
				EmailVerifiedAt:  pointy.GetPointer(modelx.FormatNullDotTime(v.UserEmailVerifiedAt, "")),
				MobileVerified:   pointy.GetPointer(MobileVerified),
				MobileVerifiedAt: pointy.GetPointer(modelx.FormatNullDotTime(v.UserMobileVerifiedAt, "")),
				CreatedIP:        pointy.GetPointer(v.CreateIP),
				IsSystem:         pointy.GetPointer(IsSystem),
			})
		}
	}
	return resp, nil
}
